package ninetails;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.IOException;
import java.net.URI;
import java.text.MessageFormat;
import java.util.Locale;
import java.util.ResourceBundle;
import java.util.logging.Level;
import java.util.logging.Logger;

public class GUI
    extends JFrame
    implements ActionListener
{
  private static final Logger log = Logger.getLogger("GUI");
  private static final ResourceBundle bundle = ResourceBundle.getBundle(Literals.STRINGBUNDLE, Locale.getDefault());
  private final JMenuItem fileExit = new JMenuItem();
  private final JMenuItem fileOptions = new JMenuItem();
//  private final JMenuItem helpAbout = new JMenuItem();
  private final JMenuItem helpDocs = new JMenuItem();
  private final RLVibe rlvibe;
  private final JLabel titleText = new JLabel();
  private final JLabel statusText = new JLabel();
  private final MessageFormat formatter = new MessageFormat("");


  public GUI()
  {
    initComponents();
    try
    {
      RLVibe.newInstance();
    }
    catch (UnsatisfiedLinkError linkError)
    {
      log.severe(linkError.getLocalizedMessage());
      log.log(Level.FINEST, linkError.getLocalizedMessage(), linkError);
      initializationError(linkError);
      System.exit(-1);
    }
    rlvibe = RLVibe.getInstance();
    rlvibe.setGUI(this);
//    if (args.length > 0)
//    {
//      try
//      {
//        final URL rlvibeHost = new URL(args[0]);
//        Thread thread = new Thread() {
//          public void run()
//          {
//            try
//            {
//              rlvibe.connect(rlvibeHost);
//            }
//            catch (IOException e)
//            {
//              e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
//            }
//          }
//        };
//        thread.start();
//      }
//      catch (MalformedURLException e)
//      {
//        e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
//      }
//    }
  }

  public static void initializationError(final Throwable exception)
  {
    final String msg = exception.getLocalizedMessage();
    final String exitMsg = bundle.getString("program.exit");
    final StringBuilder errorMsg = new StringBuilder(msg).append(Toolbox.lineSeparator).append(exitMsg);

    // is not a valid Win32 application.
    // 64 bit version of java (only on windows?) can't load libusb
//    if (msg.indexOf("is not a valid Win32 application.") != -1)
//    {}

    // The specified module could not be found
    // this means we can't find libusb-1.0.dll in the path


    // Check to see if this is Windows and they didn't install the device driver.
    if (msg.indexOf("TODO - I don't know what this error message is yet") != -1)
    {
      errorMsg.setLength(0);
      errorMsg.append(bundle.getString("win32.driver.missing"));
      final int reply = JOptionPane.showConfirmDialog(null,
                                                      errorMsg.toString(),
                                                      bundle.getString("error.usb.initialization"),
                                                      JOptionPane.YES_NO_OPTION);
      if (reply == JOptionPane.YES_OPTION)
        Toolbox.openUrl("http://code.google.com/p/rlvibe/downloads/detail?name=RLVibe-driver-setup.exe");
      return;
    }

    JOptionPane.showMessageDialog(null,
                                  errorMsg.toString(),
                                  bundle.getString("error.usb.initialization"),
                                  JOptionPane.ERROR_MESSAGE);
  }

  private void initComponents()
  {
    formatter.setLocale(Locale.getDefault());
    setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);

    final JMenuBar menuBar = new JMenuBar();
    final JMenu fileMenu = new JMenu();
    final JMenu helpMenu = new JMenu();

    fileMenu.setText(bundle.getString("File"));
    fileMenu.setMnemonic(bundle.getString("FileMnemonic").charAt(0));

    fileExit.setText(bundle.getString("Exit"));
    fileExit.setMnemonic(bundle.getString("ExitMnemonic").charAt(0));
    fileExit.addActionListener(this);

//    fileOptions.setText(bundle.getString("Options"));
//    fileOptions.addActionListener(this);
//    fileOptions.setMnemonic(bundle.getString("OptionsMnemonic").charAt(0));
//
//    fileMenu.add(fileOptions);
    fileMenu.add(fileExit);

    helpMenu.setText(bundle.getString("Help"));
    helpMenu.setMnemonic(bundle.getString("HelpMnemonic").charAt(0));

//    helpAbout.setText(bundle.getString("About"));
//    helpAbout.addActionListener(this);
//    helpAbout.setMnemonic(bundle.getString("AboutMnemonic").charAt(0));

    helpDocs.setText(bundle.getString("Docs"));
    helpDocs.addActionListener(this);
    helpDocs.setMnemonic(bundle.getString("DocsMnemonic").charAt(0));

//    helpMenu.add(helpAbout);
    helpMenu.add(helpDocs);

    menuBar.add(fileMenu);
    menuBar.add(helpMenu);
    setJMenuBar(menuBar);

    final JPanel northPanel = new JPanel();
    northPanel.add(titleText);

    final JPanel southPanel = new JPanel();
    statusText.setText(bundle.getString(Literals.DISCONNECTED));
    southPanel.add(statusText);


    addWindowListener(new WindowAdapter()
    {
      @Override
      public void windowClosing(final WindowEvent e)
      {
        //super.windowClosing(evt);
        closeWindow();
      }
    });

    getContentPane().setLayout(new BorderLayout());
    add(Toolbox.NORTH, northPanel);
    add(Toolbox.SOUTH, southPanel);
    setSize(400, 200);

    setTitle("RLVibe - by Kittin Ninetails");
//    pack();
//    final Dimension size = Toolkit.getDefaultToolkit().getScreenSize();
//    setLocation((int) (size.getWidth() - (double) getWidth()) >> 1,
//                (int) (size.getHeight() - (double) getHeight()) >> 1);
    setLocation(Toolbox.centerScreen(this));
  }

  /**
   * Handler to process closing down of the application.
   */
  private void closeWindow()
  {
//    if (config.isDirty())
//    {
//      final int value = JOptionPane.showOptionDialog(null,
//                                                     "Do you want to save your provisioning data?",
//                                                     "Unsaved Provisioning Data",
//                                                     JOptionPane.YES_NO_CANCEL_OPTION,
//                                                     JOptionPane.QUESTION_MESSAGE,
//                                                     null, null, null);
//      switch (value)
//      {
//        case JOptionPane.YES_OPTION:
//          if (fileSaveActionPerformed())
//            System.exit(0);
//          break;
//        case JOptionPane.NO_OPTION:
//          System.exit(0);
//          break;
//        case JOptionPane.CANCEL_OPTION:
//        default:
//      }
//    }
//    else
    rlvibe.closeDevice();
    System.exit(0);
  }

  public void actionPerformed(ActionEvent e)
  {
    if (e.getSource() == fileExit)
      fileExitActionPerformed();
//    else if (e.getSource() == helpAbout)
//    {
//      new About(this);
//    }
    else if (e.getSource() == helpDocs)
    {
      try
      {
        Desktop.getDesktop().browse(URI.create(bundle.getString("onlineDocsURL")));
      }
      catch (IOException ignore)
      {
        JOptionPane.showOptionDialog(null,
                                     bundle.getString("error.documentation"),
                                     bundle.getString("error.documentation.title"),
                                     JOptionPane.DEFAULT_OPTION,
                                     JOptionPane.ERROR_MESSAGE,
                                     null, null, null);
      }
    }
    else
      System.err.println("Action not handled: " + e.getActionCommand());
  }

  /**
   * Action to perform when File|Exit is selected from the menubar.
   */
  private void fileExitActionPerformed()
  {
    closeWindow();
  }

  public void setStatusMessage(final String msg)
  {
    statusText.setText(bundle.getString(msg));
  }

  public void setStatusMessageRaw(final String msg)
  {
    statusText.setText(msg);
  }

  public void setStatusMessage(final String msg, final Object[] parameters)
  {
    formatter.applyPattern(bundle.getString(msg));
    statusText.setText(formatter.format(parameters));
  }

  public String getStatusMessage()
  {
    return statusText.getText();
  }

  public void setStatusMessage(final int msg)
  {
    statusText.setText(String.valueOf(msg) + '%');
  }

  public void setTitleText(final String msg)
  {
    titleText.setText(msg);
  }
}
